use std::{sync::{mpsc, Arc, Mutex}, thread, time::Duration};

fn main() {
    mutex_test();
}

fn thread_test() {
    let v = vec![1, 2, 3];

    // move 将当前作用域中v的所有权移动到线程内
    let t = thread::spawn(move || {
        for i in 1..3 {
            println!("{}", i);
        }
        println!("v:{:?}", v);
    });

    // 线程需要所有权的原因：
    // 在线程运行过程中，变量可能发生修复，导致非预期的错误
    //drop(v);

    t.join().unwrap();
}

fn channel_test() {
    // let 解构变量
    let (tx, rx) = mpsc::channel();
    let tx2 = mpsc::Sender::clone(&tx);

    thread::spawn(move || {
        let msg = String::from("hi");
        // send会获取发送变量的所有权
        tx.send(msg).unwrap();
    });

    thread::spawn(move || {
        thread::sleep(Duration::from_secs(1));
        tx2.send(String::from("world")).unwrap();
    });

    let received = rx.recv().unwrap();
    println!("receive: {}", received);

    for received in rx {
        println!("--> {}", received);
    }
}

fn mutex_test() {
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();
            *num += 1; 
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }

    println!("counter: {}", *counter.lock().unwrap())
}